package org.example.user.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.example.loginAop.annotation.AnnAop;
import org.example.loginAop.utils.Result;
import org.example.user.domain.*;
import org.example.user.service.*;
import org.example.user.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("user")
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private UseronlinService useronlinService;
    @AnnAop("ceo")
    @RequestMapping("enroll")
    public Result enroll(@RequestBody User user, HttpServletRequest request){
        String ip = request.getRemoteAddr();

        String s = DigestUtil.md5Hex(user + ip);
        if(!redisTemplate.opsForValue().setIfAbsent(s,"1111",5,TimeUnit.SECONDS)){
            return Result.fail("请勿重复注册用户");

        }
        boolean save = userService.saveAll(user);
        return save?Result.success():Result.fail();

    }
    @RequestMapping("login")
    public CompletableFuture<Result> login(@RequestBody User user,HttpServletRequest request){
        CompletableFuture<Result> resultCompletableFuture = CompletableFuture.supplyAsync(() -> {
            String ip = request.getRemoteAddr();
            String s = DigestUtil.md5Hex(user + ip);
            if (!redisTemplate.opsForValue().setIfAbsent(s, "2222", 5, TimeUnit.SECONDS)) {
                return Result.fail("请勿重复登录");
            }
            User dbUser = userService.getUserByUserName(user.getUsername());
            if (dbUser == null) {
                return Result.fail("用户名不存在");
            }
            String pwd = DigestUtil.md5Hex(user.getPassword() + dbUser.getSalt());
            if (!pwd.equals(dbUser.getPassword())) {
                return Result.fail("密码错误");
            }
            String token = JwtUtils.createToken(dbUser);
            redisTemplate.opsForValue().set("token" + ip, token, 30, TimeUnit.MINUTES);

            //统计在线用户表，进行筛选，如果有修改登录时间，如果没有进行添加
            LambdaQueryWrapper<Useronlin> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Useronlin::getUserId, dbUser.getId());
            wrapper1.eq(Useronlin::getIp, ip);
            Useronlin one = useronlinService.getOne(wrapper1);
            if (one == null) {
                Useronlin useronlin = new Useronlin();
                useronlin.setUserId(dbUser.getId());
                useronlin.setCreatime(new Date());
                useronlin.setIp(ip);
                useronlinService.save(useronlin);
            } else {
                one.setCreatime(new Date());
                useronlinService.updateById(one);
            }
            return Result.success(token);
        });
        return resultCompletableFuture;
    }
    @RequestMapping("/list")
    public Result list(@RequestBody User user, Integer current,Integer size){
        PageHelper.startPage(current,size);
        List<User> list = userService.listAll(user);
        return Result.success(new PageInfo<>(list));
    }

    //在线用户统计
    @RequestMapping("/online")
    public Result online(){
        Integer sum=useronlinService.getsum();
        return Result.success(sum);
    }
    //(强退)如果用户登录时间超过一定时间，那么删除token，进行退出
    @RequestMapping("forced")
    public Result forced(HttpServletRequest request){
        String ip = request.getRemoteAddr();
        String token = (String) redisTemplate.opsForValue().get("token"+ip);
        Map user = (Map) JwtUtils.parseToken(token);
        Integer id = (Integer) user.get("id");
        LambdaQueryWrapper<Useronlin> useronlinLambdaQueryWrapper = new LambdaQueryWrapper<>();
        useronlinLambdaQueryWrapper.eq(Useronlin::getUserId,id);
        Useronlin one = useronlinService.getOne(useronlinLambdaQueryWrapper);
        Date creatime = one.getCreatime();
        DateTime dateTime = DateUtil.offsetMinute(creatime, 10);
        Date date = new Date();
        int compare = DateUtil.compare(date, dateTime);
        if(compare>0){
            boolean b = useronlinService.removeById(one);
            return Result.success();
        }
        return Result.fail();
    }
    @RequestMapping("forceduser")
    public Result forceduser(@RequestBody Useronlin useronlin ,HttpServletRequest request, HttpServletResponse response) throws IOException {
        String ip = request.getRemoteAddr();
        if(redisTemplate.hasKey("token" + ip)){
            Boolean b = redisTemplate.delete("token" + useronlin.getIp());
            LambdaQueryWrapper<Useronlin> useronlinLambdaQueryWrapper = new LambdaQueryWrapper<>();
            useronlinLambdaQueryWrapper.eq(Useronlin::getUserId,useronlin.getUserId());
            useronlinLambdaQueryWrapper.eq(Useronlin::getIp,useronlin.getIp());
            Useronlin one = useronlinService.getOne(useronlinLambdaQueryWrapper);
            useronlinService.removeById(one);
            return Result.success();
        }
        return Result.fail();
    }
    //(自动退)删除token，进行退出
    @RequestMapping("/exit")
    public Result exit(HttpServletRequest request){
        String ip = request.getRemoteAddr();
        if(redisTemplate.hasKey("token")){
            String token = (String) redisTemplate.opsForValue().get("token"+ip);
            Map user = (Map) JwtUtils.parseToken(token);
            Integer id = (Integer) user.get("id");
            LambdaQueryWrapper<Useronlin> useronlinLambdaQueryWrapper = new LambdaQueryWrapper<>();
            useronlinLambdaQueryWrapper.eq(Useronlin::getUserId,id);
            Useronlin one = useronlinService.getOne(useronlinLambdaQueryWrapper);
            useronlinService.removeById(one);
            Boolean b = redisTemplate.delete("token"+ip);
            return b?Result.success():Result.fail();
        }
        return Result.success();
    }
    @RequestMapping("/onlinelist")
    public Result onlinelist(){
        List<Useronlin> list = useronlinService.listall();
        return Result.success(list);
    }
    @RequestMapping("/update")
    public Result del(@RequestBody User user){
        boolean b = userService.updateAll(user);
        return b?Result.success():Result.fail();
    }
    @Autowired
    private RoleService roleService;
    @Autowired
    private DeptService deptService;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @RequestMapping("list2")
    public void list2(){
        for (int i = 0; i < 3; i++) {

            threadPoolTaskExecutor.execute(()->{
                log.info("线程：执行了");
                List<User> list = userService.list();
                System.out.println(list);
                List<UserRole> list1 = userRoleService.list();
                System.out.println(list1);
                List<Role> list2 = roleService.list();
                System.out.println(list2);
                List<Dept> list3 = deptService.list();
                System.out.println(list3);
            });

        }


    }
    @RequestMapping("list3")
    public void list3(){
        List<User> list = userService.list();
        System.out.println(list);
        List<UserRole> list1 = userRoleService.list();
        System.out.println(list1);
        List<Role> list2 = roleService.list();
        System.out.println(list2);
        List<Dept> list3 = deptService.list();
        System.out.println(list3);
    }
}
